package com.freewater.library.lending.book.model;

import com.freewater.library.catalogue.model.Book;
import com.freewater.library.common.domain.DomainException;
import com.freewater.library.common.domain.DomainService;
import com.freewater.library.lending.reader.model.Reader;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.Validate;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Random;

@RequiredArgsConstructor
public class BookLendingService implements DomainService {

    private final BookInstanceRepository bookInstanceRepository;

    /**
     * 预定书
     *
     * @param book   书
     * @param reader 读者
     * @return 预定成功的书
     */
    public BookInstance reserveBook(Book book, Reader reader) {
        Validate.notNull(book, "预定书不能为空");
        Validate.notNull(reader, "读者不能为空");
        if (reader.isSuspended()) {
            throw new DomainException("当前读者已被禁止借阅图书");
        }
        if (reader.getBooksOccupied() + 1 > Reader.MAX_OCCUPY_BOOK_COUNT) {
            throw new DomainException("已超过读者可借阅/预定的书籍数量");
        }
        String isbn = book.getIsbn();
        List<BookInstance> bookInstances = this.bookInstanceRepository.findCanBeReservedBooks(isbn);
        if (bookInstances.isEmpty()) {
            throw new DomainException("没有任何可预定的书");
        }
        // 随机找出一本可借阅的BookInstance
        BookInstance bookInstance = this.randomReserve(bookInstances);
        bookInstance.reserve(reader.getId(), LocalDateTime.now());
        return bookInstance;
    }

    /**
     * 借出书
     *
     * @param bookInstance 被借出的书
     * @param reader       读者
     */

    public void checkOut(BookInstance bookInstance, Reader reader) {
        Validate.notNull(bookInstance, "借出书不能为空");
        Validate.notNull(reader, "读者不能为空");
        if (reader.isSuspended()) {
            throw new DomainException("当前读者已被禁止借阅图书");
        }
        if (bookInstance.isReservingBy(reader.getId())) {
            bookInstance.checkOut(reader.getId(), LocalDateTime.now());
            return;
        }
        if (reader.getBooksOccupied() + 1 > Reader.MAX_OCCUPY_BOOK_COUNT) {
            throw new DomainException("已超过读者可借阅/预定的书籍数量");
        }
        bookInstance.checkOut(reader.getId(), LocalDateTime.now());
    }

    /**
     * 随机选取一本书
     *
     * @param bookInstances 书列表
     * @return 随机的一本书
     */
    private BookInstance randomReserve(List<BookInstance> bookInstances) {
        Random random = new Random();
        int index = random.nextInt(bookInstances.size());
        return bookInstances.get(index);
    }
}
